#ifndef __VIRTUAL_MATCH_RINGBUF_H__
#define __VIRTUAL_MATCH_RINGBUF_H__

#include    <cstdlib>
#include    <iomanip>

#include <boost/cstdint.hpp>
#include <boost/memory_order.hpp>

#include <disruptor/event_processor.h>
#include <disruptor/ring_buffer.h>

#include "OrderEvent.h"
#include "TradeStubEvent.h"

#define BUFFER_SIZE 64


class RingBufferOrder {

public:
	RingBufferOrder() :
	factory(new OrderEventFactory()),
	ring_buffer(factory,
	BUFFER_SIZE,
	disruptor::kSingleThreadedStrategy,
	disruptor::kSleepingStrategy),
	stub_processor(&ring_buffer) {
		std::vector<disruptor::Sequence*> sequences;
		sequences.push_back(stub_processor.GetSequence());
		ring_buffer.set_gating_sequences(sequences);
		std::vector<disruptor::Sequence*> empty_sequences(0);
		barrier = (disruptor::SequenceBarrierInterface*) ring_buffer.NewBarrier(empty_sequences);
}

~RingBufferOrder() {}

public:
	static RingBufferOrder* Instance()
	{
		static RingBufferOrder s_rbo;
		return &s_rbo;
	}

public:
//void FillBuffer() {
//	for (int i = 0; i < BUFFER_SIZE; i++) {
//		int64_t sequence = ring_buffer.Next();
//		ring_buffer.Publish(sequence);
//	}
//}


OrderEventFactory* factory;
disruptor::RingBuffer<OrderEvent> ring_buffer;
disruptor::NoOpEventProcessor<OrderEvent> stub_processor;
disruptor::SequenceBarrierInterface* barrier;
};


struct RingBufferTrade {
protected:
	RingBufferTrade() :
factory(new TradeStubEventFactory()),
ring_buffer(factory,
			BUFFER_SIZE,
			disruptor::kSingleThreadedStrategy,
			disruptor::kSleepingStrategy),
			stub_processor(&ring_buffer) {
				std::vector<disruptor::Sequence*> sequences;
				sequences.push_back(stub_processor.GetSequence());
				ring_buffer.set_gating_sequences(sequences);
				std::vector<disruptor::Sequence*> empty_sequences(0);
				barrier = (disruptor::SequenceBarrierInterface*) ring_buffer.NewBarrier(empty_sequences);
}

~RingBufferTrade() {}

public:
	static RingBufferTrade* Instance()
	{
		static RingBufferTrade s_rbo;
		return &s_rbo;
	}
//void FillBuffer() {
//	for (int i = 0; i < BUFFER_SIZE; i++) {
//		int64_t sequence = ring_buffer.Next();
//		ring_buffer.Publish(sequence);
//	}
//}

public:

TradeStubEventFactory* factory;
disruptor::RingBuffer<TradeStubEvent> ring_buffer;
disruptor::NoOpEventProcessor<TradeStubEvent> stub_processor;
disruptor::SequenceBarrierInterface* barrier;
};

#endif
